import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor"
import { ACTOR_TYPE } from "../interface"
import { BActor } from "./BActor"
import vtkPoints from "@kitware/vtk.js/Common/Core/Points"
import vtkGlyph3DMapper from "@kitware/vtk.js/Rendering/Core/Glyph3DMapper"
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData"
import vtkArrowSource from "@kitware/vtk.js/Filters/Sources/ArrowSource"
import vtkDataArray from "@kitware/vtk.js/Common/Core/DataArray"

export class NormalActor extends BActor {
    instance: any = vtkActor.newInstance()
    type: ACTOR_TYPE = ACTOR_TYPE.GRAPHIC_ACTOR
    createdBy: string = "default"
    private points = vtkPoints.newInstance()
    private polyData = vtkPolyData.newInstance()
    private mapper = vtkGlyph3DMapper.newInstance({
        useLookupTableScalarRange: false,
    })
    centers: number[] = []
    normals: number[] = []
    factorSize = 15

    constructor(centers: number[], normals: number[]) {
        super()
        this.centers = centers
        this.normals = normals
        this.createPoints()
        this.createDataMap()
        this.instance.setMapper(this.mapper)
        this.setColor([0, 255, 0])
    }

    setColor(color: number[]) {
        this.instance
            .getProperty()
            .setColor(color[0] / 255, color[1] / 255, color[2] / 255)
    }

    createPoints() {
        const points = new Float32Array(this.centers)
        this.points.setData(points, 3)
        this.polyData.setPoints(this.points)
        this.polyData.getPointData().setNormals(
            vtkDataArray.newInstance({
                name: "Normals",
                values: [...this.normals],
                numberOfComponents: 3, // 法线向量的分量个数
            })
        )
    }

    createDataMap() {
        const arrowSource = vtkArrowSource.newInstance()
        const glyphMapper = this.mapper
        glyphMapper.setInputData(this.polyData)
        glyphMapper.setSourceConnection(arrowSource.getOutputPort())
        glyphMapper.setOrientationModeToDirection()
        glyphMapper.setOrientationArray("Normals")
        glyphMapper.setScaleModeToScaleByMagnitude()
        //@ts-ignore
        glyphMapper.setScaleArray("Normals")
        glyphMapper.setScaleFactor(this.factorSize)
    }

    set visible(visible: boolean) {
        this.instance.setVisibility(visible)
    }

    get visible() {
        return this.instance.getVisibility()
    }

    setScaleFactor(factor: number) {
        this.factorSize = factor
        this.mapper.setScaleFactor(this.factorSize)
        this.mapper.modified()
        this.mapper.update()
    }
}
